<?php
function addStr(...$vars): string
{
    $s = '';
    foreach ($vars as $v) {
        $s .= $v . ' ';
    }
    return $s;
}

/**
 * @param  array  $items 需要处理的数组
 * @param  string $parent_key 绑定上下级关系的字段名
 * @return array  $tree  树结构数组
 */
function toTree($items, $parent_key = 'parent_id')
{
    $items = array_column($items, null, 'id');
    $tree = [];
    foreach ($items as $item) {
        if (isset($items[$item[$parent_key]])) {
            $items[$item[$parent_key]]['children'][] = &$items[$item['id']];
        } else {
            $tree[] = &$items[$item['id']];
        }
    }
    return $tree;
}

/**
 * 说明：动态修改 env 配置文件
 *
 * @return
 * @param   array|string $env_data ["LOGIN_CAPTCHA" => "false"] | FLOW_BACK=false;LOGIN_CAPTCHA=false;EVALUATION_COURSE_HINT='请认真评价噢~'
 * @param   string $value 当传入 $value 时 表示单独设置一个 env 配置项  此时$env_data为key
 * @author  daixinguo (daixinguo57@163.com)
 */
function envSet($env_data, $value = '')
{
    if ($value != '' && is_string($env_data)) {
        $env_data = [$env_data => $value];
    }

    if (!is_array($env_data)) {
        $env_data_arr = explode(";", $env_data);
        $env_data = [];
        foreach ($env_data_arr as $env) {
            [$env_key, $env_value] = explode("=", $env);
            $env_data[$env_key] = $env_value;
        }
    }

    $envPath = base_path() . DIRECTORY_SEPARATOR . '.env';
    $env_collect = collect(file($envPath, FILE_IGNORE_NEW_LINES));
    $all_env_keys = [];
    foreach ($env_collect as $key => $value) {
        if (Str::contains($value, '=')) {
            [$env_key, $env_value] = explode("=", $value);
            $all_env_keys[] = $env_key;
            if (in_array($env_key, ['AUTHORIZE_SITE_KEY', 'AUTHORIZE_DOMAIN', 'AUTHORIZE_IP', 'VERSION'])) {
                // ['AUTHORIZE_SITE_KEY', 'AUTHORIZE_DOMAIN', 'AUTHORIZE_IP', 'VERSION'] 不允许修改
                continue;
            }
            if (isset($env_data[$env_key])) {
                $env_collect[$key] = "{$env_key}={$env_data[$env_key]}";
            }
        }
    }

    foreach ($env_data as $key => $value) {
        if (!in_array($key, $all_env_keys)) {
            $env_collect[] = "{$key}={$value}";
        }
    }
    $env_content = implode("\n", $env_collect->toArray());

    try {
        file_put_contents($envPath, $env_content);
    } catch (\Throwable $th) {
        return false;
    }

    return $env_collect->toArray();
}

/**
 * 说明：数组深层迭代【不支持无限级节点迭代，最多支持 20 级】
 *
 * @return boolean
 * @param  array $data  需要迭代的数组
 * @param  string $node 节点（多级使用 "." 分割，例如：evaluation_courses_groups.group_experts）
 * @param  mixed $node_item 迭代到数组指定节点下的值
 * @param  mixed $empty_and_set 是否为空时才赋值
 * @author  daixinguo (daixinguo57@163.com)
 */
function iterationNodeData(array &$data, string $node, $node_item, $empty_and_set = false)
{
    $nodes = explode(".", $node);
    $node_count = count($nodes);
    if ($node_count > 20) {
        throw new Exception("节点层级最多支持20级！");
    }
    switch ($node_count) {
        case 1:
            if ($empty_and_set) {
                if (!isset($data[$nodes[0]])) {
                    $data[$nodes[0]] = $node_item;
                }
            } else {
                $data[$nodes[0]] = $node_item;
            }
            break;
        case 2:
            if ($empty_and_set) {
                if (!isset($data[$nodes[0]][$nodes[1]])) {
                    $data[$nodes[0]][$nodes[1]] = $node_item;
                }
            } else {
                $data[$nodes[0]][$nodes[1]] = $node_item;
            }
            break;
        case 3:
            if ($empty_and_set) {
                if (!isset($data[$nodes[0]][$nodes[1]][$nodes[2]])) {
                    $data[$nodes[0]][$nodes[1]][$nodes[2]] = $node_item;
                }
            } else {
                $data[$nodes[0]][$nodes[1]][$nodes[2]] = $node_item;
            }
            break;
        case 4:
            if ($empty_and_set) {
                if (!isset($data[$nodes[0]][$nodes[1]][$nodes[2]][$nodes[3]])) {
                    $data[$nodes[0]][$nodes[1]][$nodes[2]][$nodes[3]] = $node_item;
                }
            } else {
                $data[$nodes[0]][$nodes[1]][$nodes[2]][$nodes[3]] = $node_item;
            }
            break;
        case 5:
            if ($empty_and_set) {
                if (!isset($data[$nodes[0]][$nodes[1]][$nodes[2]][$nodes[3]][$nodes[4]])) {
                    $data[$nodes[0]][$nodes[1]][$nodes[2]][$nodes[3]][$nodes[4]] = $node_item;
                }
            } else {
                $data[$nodes[0]][$nodes[1]][$nodes[2]][$nodes[3]][$nodes[4]] = $node_item;
            }
            break;
        case 6:
            if ($empty_and_set) {
                if (!isset($data[$nodes[0]][$nodes[1]][$nodes[2]][$nodes[3]][$nodes[4]][$nodes[5]])) {
                    $data[$nodes[0]][$nodes[1]][$nodes[2]][$nodes[3]][$nodes[4]][$nodes[5]] = $node_item;
                }
            } else {
                $data[$nodes[0]][$nodes[1]][$nodes[2]][$nodes[3]][$nodes[4]][$nodes[5]] = $node_item;
            }
            break;
        case 7:
            if ($empty_and_set) {
                if (!isset($data[$nodes[0]][$nodes[1]][$nodes[2]][$nodes[3]][$nodes[4]][$nodes[5]][$nodes[6]])) {
                    $data[$nodes[0]][$nodes[1]][$nodes[2]][$nodes[3]][$nodes[4]][$nodes[5]][$nodes[6]] = $node_item;
                }
            } else {
                $data[$nodes[0]][$nodes[1]][$nodes[2]][$nodes[3]][$nodes[4]][$nodes[5]][$nodes[6]] = $node_item;
            }
            break;
        case 8:
            if ($empty_and_set) {
                if (!isset($data[$nodes[0]][$nodes[1]][$nodes[2]][$nodes[3]][$nodes[4]][$nodes[5]][$nodes[6]][$nodes[7]])) {
                    $data[$nodes[0]][$nodes[1]][$nodes[2]][$nodes[3]][$nodes[4]][$nodes[5]][$nodes[6]][$nodes[7]] = $node_item;
                }
            } else {
                $data[$nodes[0]][$nodes[1]][$nodes[2]][$nodes[3]][$nodes[4]][$nodes[5]][$nodes[6]][$nodes[7]] = $node_item;
            }
            break;
        case 9:
            if ($empty_and_set) {
                if (!isset($data[$nodes[0]][$nodes[1]][$nodes[2]][$nodes[3]][$nodes[4]][$nodes[5]][$nodes[6]][$nodes[7]][$nodes[8]])) {
                    $data[$nodes[0]][$nodes[1]][$nodes[2]][$nodes[3]][$nodes[4]][$nodes[5]][$nodes[6]][$nodes[7]][$nodes[8]] = $node_item;
                }
            } else {
                $data[$nodes[0]][$nodes[1]][$nodes[2]][$nodes[3]][$nodes[4]][$nodes[5]][$nodes[6]][$nodes[7]][$nodes[8]] = $node_item;
            }
            break;
        case 10:
            if ($empty_and_set) {
                if (!isset($data[$nodes[0]][$nodes[1]][$nodes[2]][$nodes[3]][$nodes[4]][$nodes[5]][$nodes[6]][$nodes[7]][$nodes[8]][$nodes[9]])) {
                    $data[$nodes[0]][$nodes[1]][$nodes[2]][$nodes[3]][$nodes[4]][$nodes[5]][$nodes[6]][$nodes[7]][$nodes[8]][$nodes[9]] = $node_item;
                }
            } else {
                $data[$nodes[0]][$nodes[1]][$nodes[2]][$nodes[3]][$nodes[4]][$nodes[5]][$nodes[6]][$nodes[7]][$nodes[8]][$nodes[9]] = $node_item;
            }
            break;
        case 11:
            if ($empty_and_set) {
                if (!isset($data[$nodes[0]][$nodes[1]][$nodes[2]][$nodes[3]][$nodes[4]][$nodes[5]][$nodes[6]][$nodes[7]][$nodes[8]][$nodes[9]][$nodes[10]])) {
                    $data[$nodes[0]][$nodes[1]][$nodes[2]][$nodes[3]][$nodes[4]][$nodes[5]][$nodes[6]][$nodes[7]][$nodes[8]][$nodes[9]][$nodes[10]] = $node_item;
                }
            } else {
                $data[$nodes[0]][$nodes[1]][$nodes[2]][$nodes[3]][$nodes[4]][$nodes[5]][$nodes[6]][$nodes[7]][$nodes[8]][$nodes[9]][$nodes[10]] = $node_item;
            }
            break;
        case 12:
            if ($empty_and_set) {
                if (!isset($data[$nodes[0]][$nodes[1]][$nodes[2]][$nodes[3]][$nodes[4]][$nodes[5]][$nodes[6]][$nodes[7]][$nodes[8]][$nodes[9]][$nodes[10]][$nodes[11]])) {
                    $data[$nodes[0]][$nodes[1]][$nodes[2]][$nodes[3]][$nodes[4]][$nodes[5]][$nodes[6]][$nodes[7]][$nodes[8]][$nodes[9]][$nodes[10]][$nodes[11]] = $node_item;
                }
            } else {
                $data[$nodes[0]][$nodes[1]][$nodes[2]][$nodes[3]][$nodes[4]][$nodes[5]][$nodes[6]][$nodes[7]][$nodes[8]][$nodes[9]][$nodes[10]][$nodes[11]] = $node_item;
            }
            break;
        case 13:
            if ($empty_and_set) {
                if (!isset($data[$nodes[0]][$nodes[1]][$nodes[2]][$nodes[3]][$nodes[4]][$nodes[5]][$nodes[6]][$nodes[7]][$nodes[8]][$nodes[9]][$nodes[10]][$nodes[11]][$nodes[12]])) {
                    $data[$nodes[0]][$nodes[1]][$nodes[2]][$nodes[3]][$nodes[4]][$nodes[5]][$nodes[6]][$nodes[7]][$nodes[8]][$nodes[9]][$nodes[10]][$nodes[11]][$nodes[12]] = $node_item;
                }
            } else {
                $data[$nodes[0]][$nodes[1]][$nodes[2]][$nodes[3]][$nodes[4]][$nodes[5]][$nodes[6]][$nodes[7]][$nodes[8]][$nodes[9]][$nodes[10]][$nodes[11]][$nodes[12]] = $node_item;
            }
            break;
        case 14:
            if ($empty_and_set) {
                if (!isset($data[$nodes[0]][$nodes[1]][$nodes[2]][$nodes[3]][$nodes[4]][$nodes[5]][$nodes[6]][$nodes[7]][$nodes[8]][$nodes[9]][$nodes[10]][$nodes[11]][$nodes[12]][$nodes[13]])) {
                    $data[$nodes[0]][$nodes[1]][$nodes[2]][$nodes[3]][$nodes[4]][$nodes[5]][$nodes[6]][$nodes[7]][$nodes[8]][$nodes[9]][$nodes[10]][$nodes[11]][$nodes[12]][$nodes[13]] = $node_item;
                }
            } else {
                $data[$nodes[0]][$nodes[1]][$nodes[2]][$nodes[3]][$nodes[4]][$nodes[5]][$nodes[6]][$nodes[7]][$nodes[8]][$nodes[9]][$nodes[10]][$nodes[11]][$nodes[12]][$nodes[13]] = $node_item;
            }
            break;
        case 15:
            if ($empty_and_set) {
                if (!isset($data[$nodes[0]][$nodes[1]][$nodes[2]][$nodes[3]][$nodes[4]][$nodes[5]][$nodes[6]][$nodes[7]][$nodes[8]][$nodes[9]][$nodes[10]][$nodes[11]][$nodes[12]][$nodes[13]][$nodes[14]])) {
                    $data[$nodes[0]][$nodes[1]][$nodes[2]][$nodes[3]][$nodes[4]][$nodes[5]][$nodes[6]][$nodes[7]][$nodes[8]][$nodes[9]][$nodes[10]][$nodes[11]][$nodes[12]][$nodes[13]][$nodes[14]] = $node_item;
                }
            } else {
                $data[$nodes[0]][$nodes[1]][$nodes[2]][$nodes[3]][$nodes[4]][$nodes[5]][$nodes[6]][$nodes[7]][$nodes[8]][$nodes[9]][$nodes[10]][$nodes[11]][$nodes[12]][$nodes[13]][$nodes[14]] = $node_item;
            }
            break;
        case 16:
            if ($empty_and_set) {
                if (!isset($data[$nodes[0]][$nodes[1]][$nodes[2]][$nodes[3]][$nodes[4]][$nodes[5]][$nodes[6]][$nodes[7]][$nodes[8]][$nodes[9]][$nodes[10]][$nodes[11]][$nodes[12]][$nodes[13]][$nodes[14]][$nodes[15]])) {
                    $data[$nodes[0]][$nodes[1]][$nodes[2]][$nodes[3]][$nodes[4]][$nodes[5]][$nodes[6]][$nodes[7]][$nodes[8]][$nodes[9]][$nodes[10]][$nodes[11]][$nodes[12]][$nodes[13]][$nodes[14]][$nodes[15]] = $node_item;
                }
            } else {
                $data[$nodes[0]][$nodes[1]][$nodes[2]][$nodes[3]][$nodes[4]][$nodes[5]][$nodes[6]][$nodes[7]][$nodes[8]][$nodes[9]][$nodes[10]][$nodes[11]][$nodes[12]][$nodes[13]][$nodes[14]][$nodes[15]] = $node_item;
            }
            break;
        case 17:
            if ($empty_and_set) {
                if (!isset($data[$nodes[0]][$nodes[1]][$nodes[2]][$nodes[3]][$nodes[4]][$nodes[5]][$nodes[6]][$nodes[7]][$nodes[8]][$nodes[9]][$nodes[10]][$nodes[11]][$nodes[12]][$nodes[13]][$nodes[14]][$nodes[15]][$nodes[16]])) {
                    $data[$nodes[0]][$nodes[1]][$nodes[2]][$nodes[3]][$nodes[4]][$nodes[5]][$nodes[6]][$nodes[7]][$nodes[8]][$nodes[9]][$nodes[10]][$nodes[11]][$nodes[12]][$nodes[13]][$nodes[14]][$nodes[15]][$nodes[16]] = $node_item;
                }
            } else {
                $data[$nodes[0]][$nodes[1]][$nodes[2]][$nodes[3]][$nodes[4]][$nodes[5]][$nodes[6]][$nodes[7]][$nodes[8]][$nodes[9]][$nodes[10]][$nodes[11]][$nodes[12]][$nodes[13]][$nodes[14]][$nodes[15]][$nodes[16]] = $node_item;
            }
            break;
        case 18:
            if ($empty_and_set) {
                if (!isset($data[$nodes[0]][$nodes[1]][$nodes[2]][$nodes[3]][$nodes[4]][$nodes[5]][$nodes[6]][$nodes[7]][$nodes[8]][$nodes[9]][$nodes[10]][$nodes[11]][$nodes[12]][$nodes[13]][$nodes[14]][$nodes[15]][$nodes[16]][$nodes[17]])) {
                    $data[$nodes[0]][$nodes[1]][$nodes[2]][$nodes[3]][$nodes[4]][$nodes[5]][$nodes[6]][$nodes[7]][$nodes[8]][$nodes[9]][$nodes[10]][$nodes[11]][$nodes[12]][$nodes[13]][$nodes[14]][$nodes[15]][$nodes[16]][$nodes[17]] = $node_item;
                }
            } else {
                $data[$nodes[0]][$nodes[1]][$nodes[2]][$nodes[3]][$nodes[4]][$nodes[5]][$nodes[6]][$nodes[7]][$nodes[8]][$nodes[9]][$nodes[10]][$nodes[11]][$nodes[12]][$nodes[13]][$nodes[14]][$nodes[15]][$nodes[16]][$nodes[17]] = $node_item;
            }
            break;
        case 19:
            if ($empty_and_set) {
                if (!isset($data[$nodes[0]][$nodes[1]][$nodes[2]][$nodes[3]][$nodes[4]][$nodes[5]][$nodes[6]][$nodes[7]][$nodes[8]][$nodes[9]][$nodes[10]][$nodes[11]][$nodes[12]][$nodes[13]][$nodes[14]][$nodes[15]][$nodes[16]][$nodes[17]][$nodes[18]])) {
                    $data[$nodes[0]][$nodes[1]][$nodes[2]][$nodes[3]][$nodes[4]][$nodes[5]][$nodes[6]][$nodes[7]][$nodes[8]][$nodes[9]][$nodes[10]][$nodes[11]][$nodes[12]][$nodes[13]][$nodes[14]][$nodes[15]][$nodes[16]][$nodes[17]][$nodes[18]] = $node_item;
                }
            } else {
                $data[$nodes[0]][$nodes[1]][$nodes[2]][$nodes[3]][$nodes[4]][$nodes[5]][$nodes[6]][$nodes[7]][$nodes[8]][$nodes[9]][$nodes[10]][$nodes[11]][$nodes[12]][$nodes[13]][$nodes[14]][$nodes[15]][$nodes[16]][$nodes[17]][$nodes[18]] = $node_item;
            }
            break;
        case 20:
            if ($empty_and_set) {
                if (!isset($data[$nodes[0]][$nodes[1]][$nodes[2]][$nodes[3]][$nodes[4]][$nodes[5]][$nodes[6]][$nodes[7]][$nodes[8]][$nodes[9]][$nodes[10]][$nodes[11]][$nodes[12]][$nodes[13]][$nodes[14]][$nodes[15]][$nodes[16]][$nodes[17]][$nodes[18]][$nodes[19]])) {
                    $data[$nodes[0]][$nodes[1]][$nodes[2]][$nodes[3]][$nodes[4]][$nodes[5]][$nodes[6]][$nodes[7]][$nodes[8]][$nodes[9]][$nodes[10]][$nodes[11]][$nodes[12]][$nodes[13]][$nodes[14]][$nodes[15]][$nodes[16]][$nodes[17]][$nodes[18]][$nodes[19]] = $node_item;
                }
            } else {
                $data[$nodes[0]][$nodes[1]][$nodes[2]][$nodes[3]][$nodes[4]][$nodes[5]][$nodes[6]][$nodes[7]][$nodes[8]][$nodes[9]][$nodes[10]][$nodes[11]][$nodes[12]][$nodes[13]][$nodes[14]][$nodes[15]][$nodes[16]][$nodes[17]][$nodes[18]][$nodes[19]] = $node_item;
            }
            break;
    }
    return true;
}

/**
 * 说明：获取给定数组的所有节点 key 多层节点用 "." 分割
 *
 * @return  array $node_key_values 所有节点 key-value
 * @param   array $data 给定的数组
 * @author  daixinguo (daixinguo57@163.com)
 */
function getNodeKeyValues(array $data, $node_key_values = [], $node_prefix = '', $current_key = '')
{
    $node_prefix = $node_prefix ? $node_prefix . "." . $current_key : $current_key;
    foreach ($data as $key => $value) {
        if (is_array($value)) {
            $node_key_values = getNodeKeyValues($value, $node_key_values, $node_prefix, $key);
        } else {
            $node_key = $key;
            if ($node_prefix) {
                $node_key = $node_prefix . "." . $key;
            }
            $node_key_values[$node_key] = $value;
        }
    }
    return $node_key_values;
}
